
/**
 * 从miniui原码提取类型信息
 */
const readline = require('readline');
const fs = require('fs');
let fn = "C:\\Users\\shuaihu\\OneDrive\\onGoing\\WEB\\scripts\\miniui\\miniui.js"

fReader = fs.createReadStream(fn)
let objReadline = readline.createInterface({
    input: fReader,
});
let reg = /(^[a-zA-Z\._]*) = \{/;
let objtree = {};
let obj = null;
let c = '';
let skip = 0;
let line = 0;
function getbypath(path) {
    let o;
    let a = path.split(".");
    o = objtree;
    let n = '';
    a.forEach((v, i) => {
        n = v;
        if (i == a.length - 1) return [o, v];
        if (o[v])
            o = o[v];
        else {
            if (v != 'prototype') {
                o[v] = {};
                o = o[v];
            }
        }

    })
    return [o, n];
}

let maybeobject = '';
objReadline.on('line', (str) => {
    let c;
    let s;
    line++;
    function copyto(a, b) {
        for (c in b) {
            a[c] = b[c];
        }
    }
    if (line == 4958)
        console.log(str);
    //最顶层对象或if语句结束列
    if ([1, 3, 4].includes(skip)) {
        p = str.match(/^\}/);
        if (p) {
            skip = 0;
            obj = null;
        }
        if (skip < 4) return;
    }
    //最顶层var结束列

    if (skip == 2) {
        if (str.match(".*;")) skip = 0;
        return;
    }


    //最顶层对象定义
    p = str.match(reg);
    if (p) {
        [obj, s] = getbypath(p[1])
        if (s != 'prototype') {
            obj[s] = obj[s] ? obj[s] : {};
            obj = obj[s]
        }

        skip = 0;
        return;
    }
    //copyto
    p = str.match(/^mini\.copyTo\((.*),.*\{/);
    if (p) {
        [obj, s] = getbypath(p[1])
        if (s !== 'prototype') {
            obj[s] = obj[s] ? obj[s] : {};
            obj = obj[s];
        }
        return;
    }
    //copyto from obj to obj
    p = str.match(/^mini.copyTo\((.*), (.*)\);/);
    if (p) {

        let o, c;
        [obj, s] = getbypath(p[1]);
        if (s !== 'prototype') {
            obj[s] = obj[s] ? obj[s] : {};
            obj = obj[s];
        } else {
            if (typeof obj == "string") {
                objtree.mini[p[1].split(".")[1]] = {};
                obj = objtree.mini[p[1].split(".")[1]];
            }
        }
        [o, c] = getbypath(p[2]);
        if (o && o[c]) {
            copyto(obj, o[c]);
        }
    }
    //最顶层if 或 var ...,
    p = str.match("(^if.* \{)|(^var .*[^;]$)");
    if (p) {
        if (p[1]) skip = 1; else skip = 2;
        return;
    }
    //最顶层 var ...;
    if (str.match(/^var.*;$/)) return;
    //最顶层 abc_def = function {
    p = str.match("(^[\\w\._]*) = (function.*) \\{");
    if (p) {
        [obj, s] = getbypath(p[1]);
        maybeobject = s;
        obj[s] = p[2] + ',';
        skip = 4;
        return;
    }
    //最顶层 function
    p = str.match("^function.*\\{");
    if (p) {
        skip = 3;
        return;
    }
    s = '((^' + ' '.repeat(4) + '"?([a-zA-Z]\\w*)"?: function.*) \\{)|(^' + ' '.repeat(4) + '([a-zA-Z]\\w*): ([^,\\r\\n]*),?)'
    p = str.match(s);
    //设置属性值
    if (p) {
        if (!obj)
            return;
        let pn, pv
        if (p[5]) {
            pn = p[5];
            pv = objtree[p[6]] ? pn + " : " + objtree[p[6]] : p[4];
        } else {
            pn = p[3];
            pv = p[2] + ",";
        }
        obj[pn] = pv;
    }
    p = str.match(/(^[A-Za-z][\w]*?(?:\.[A-Za-z]\w*)+) = (.*);/);
    if (p) {
        [o, s] = getbypath(p[1]);
        o[s] = p[2];
    }
    //设置属性值
    p = str.match("^ *this\\.([a-zA-Z]\\w*) = (.*;)");
    if (p) {
        if (!obj)
            return;
        if (skip == 4) {
            c = obj[maybeobject];
            obj[maybeobject] = {};
            obj = obj[maybeobject];
            obj['constructor'] = c;
            skip = 0;
        }
        if (!obj[p[1]])
            obj[p[1]] = p[2];
    }

    p = str.match(/^mini.extend\((.*?), (.*?), \{/)
    if (p) {
        skip = 0;
        [o, s] = getbypath(p[1]);
        if (typeof o[s] === 'string') {
            c = o[s];
            o[s] = {};
            obj = o[s];
            obj["constructor"] = c;
        }
        [o, s] = getbypath(p[2]);
        copyto(obj, o[s]);
        obj._supper = p[2];
        obj._osupper = o[s];
    }

})
objReadline.on("close", () => {
    s = JSON.stringify(objtree);
    fs.writeFileSync("C:\\users\\shuaihu\\miniui2.json", s);

})
